-- 游戏逻辑模块
local skynet = require "skynet"
local base = require "base"
local timetool = require "timetool"
local timer = require "timer"
local filelog = require "filelog"
local tabletool = require "tabletool"
local configdao = require "configdao"
local json = require "cjson"
json.encode_sparse_array(true, 1, 1)

require "cpcqsscenum"

local GameLogic = { }
local service = nil
local tablelogic = nil
local seatlogic = nil

--[Comment]
--init 初始化
function GameLogic.init(caller)
	service = caller
	tablelogic = service:get_logicbyname("tablelogic")
	seatlogic = service:get_logicbyname("seatlogic")
end

--[Comment]
--初始化数据,主要设置游戏状态事件对应的函数
--
function GameLogic.init_data(gameobj, tableobj)
	gameobj.tableobj = tableobj
	gameobj.stateevent[ECQSSCTableState.TABLE_STATE_GAME_START] =  GameLogic.gamestart                         --游戏开始
	gameobj.stateevent[ECQSSCTableState.TABLE_STATE_ONE_GAME_START] = GameLogic.onegamestart                   --一局游戏开始
    gameobj.stateevent[ECQSSCTableState.TABLE_STATE_PLAYER_BET] = GameLogic.playerbet                          --玩家下注
    gameobj.stateevent[ECQSSCTableState.TABLE_STATE_STOP_BET]  = GameLogic.stopbet                             --封盘
    gameobj.stateevent[ECQSSCTableState.TABLE_STATE_OPEN_AWARD] = GameLogic.openaward                          --执行开奖
    gameobj.stateevent[ECQSSCTableState.TABLE_STATE_HANDLE_OPEN_AWARD_RESULT] = GameLogic.handle_openawardresult --处理开牌结果
	gameobj.stateevent[ECQSSCTableState.TABLE_STATE_ONE_GAME_END] = GameLogic.onegameend                       --一局游戏结束
	gameobj.stateevent[ECQSSCTableState.TABLE_STATE_ONE_GAME_REAL_END] = GameLogic.onegamerealend              --一局游戏真正结束
    gameobj.stateevent[ECQSSCTableState.TABLE_STATE_GAME_END] = GameLogic.gameend                              --游戏结束

    --初始化游戏记录
    GameLogic.init_game_records(tableobj)

	return true
end

--[Comment]
-- 运行游戏，不断执行状态事件,外部接口
--
function GameLogic.run(gameobj)
	local f = nil
	while true do
        --如果未全部准备，退出
		if gameobj.tableobj.state == ECQSSCTableState.TABLE_STATE_WAIT_ALL_READY then
			break
		end

		f = gameobj.stateevent[gameobj.tableobj.state]  --获得桌子状态对应方法
		if f == nil then
			break
		end
		f(gameobj)  --执行

        --更新心跳时间
        tablelogic.update_table_heart_time(gameobj.tableobj)
	end
end

---------------------------------------------------------
---------------------------------------------------------
--[Comment]
-- TABLE_STATE_GAME_START
-- 游戏开始
-- 游戏开始---一局游戏开始---游戏----一局游戏结束----一局游戏开始---游戏--一局游戏结束--...--游戏结束
-- gameobj 游戏对象，{stateevent,tableobj}
--
function GameLogic.gamestart(gameobj)
	local tableobj = gameobj.tableobj
	GameLogic.gamestart_inittable(gameobj)
	tableobj.state = ECQSSCTableState.TABLE_STATE_ONE_GAME_START
	tableobj.is_had_start = true
end

function GameLogic.onegamestart(gameobj)
	local tableobj = gameobj.tableobj
    --一初始化游戏
	GameLogic.onegamestart_inittable(gameobj)
    --当前局数 + 1
	tableobj.curr_to_num = tableobj.curr_to_num + 1
    ---tableobj.cur_qishu = os.date("%Y%m%d", timetool.get_time()) .. "-" .. tostring(tableobj.curr_to_num)	
    --初始化游戏记录
    GameLogic.onegamestart_init_tablerecord(gameobj)
    --通知client游戏开始
	GameLogic.send_gamestart_notice(gameobj)
    tableobj.state = ECQSSCTableState.TABLE_STATE_WAIT_PLAYER_BET
    local timer_id = timer.settimer(1, "playerbet")	
	if tableobj.state ~= ECQSSCTableState.TABLE_STATE_WAIT_PLAYER_BET then
		timer.cleartimer(timer_id)
	else
		tableobj.timer_id = timer_id
	end
end

--[Comment]
--
--玩家下注
--
function GameLogic.playerbet(gameobj)
    local tableobj = gameobj.tableobj

    local now = timetool.get_time()
    tableobj.action_timeout_time = now + tableobj.do_bet_timeout
    local bet_left_time = tableobj.curr_qishu_stop_bet_time - now
    ---filelog.sys_error("-------stopbet---time------", tableobj.action_timeout_time, now, tableobj.curr_qishu_stop_bet_time, bet_left_time)
    --设置机器人下注
    local base_score_list = tabletool.deepcopy(tableobj.conf.base_score_list)
    local bet_btn_list = tabletool.deepcopy(tableobj.conf.bet_btn_list)
    local bet_time = tableobj.do_bet_timeout

    tableobj.action_timeout_time = tableobj.curr_qishu_stop_bet_time
    --通知玩家下注
    local noticemsg = {
        wait_action_type = ECQSSCActionType.ACTION_TYPE_BET,
        action_timeout_time = tableobj.action_timeout_time,
    }
    local robot_list = {}
    for _,seat in pairs(tableobj.seats) do
        if seat.state == ECQSSCSeatState.SEAT_STATE_WAIT_BET then
            if seat.is_robot then
                if seat.index ~= tableobj.banker_seat_index then
                    table.insert(robot_list,seat.rid)
                end
            else
                tablelogic.sendmsg_to_tableplayer(seat.rid, "todoN", noticemsg)
            end
        end
    end
    -- --通知机器人下注
    -- local sp_rids = { }
    -- if tableobj.special_seats_rids then
    --     for _,cur_rid in pairs(tableobj.special_seats_rids) do
    --        sp_rids[cur_rid] = true
    --     end
    -- end
    -- skynet.send(".robotmgr", "lua", "robot_do_bet", robot_list, bet_btn_list, base_score_list, bet_time, sp_rids)
    --定时等待封盘
    tableobj.state = ECQSSCTableState.TABLE_STATE_WAIT_STOP_BET
	local timer_id = timer.settimer(bet_left_time * 100, "stopbet")	
	if tableobj.state ~= ECQSSCTableState.TABLE_STATE_WAIT_STOP_BET then
		timer.cleartimer(timer_id)
	else
		tableobj.timer_id = timer_id
	end
end

---封盘(停止下注)
function GameLogic.stopbet(gameobj)
    local tableobj = gameobj.tableobj
    local nowtime = timetool.get_time()
    local award_left_time = tableobj.open_award_time - nowtime
    ---filelog.sys_error("-------stopbet---------", nowtime, tableobj.open_award_time, award_left_time)
    local noticemsg = {
        open_award_time = tableobj.open_award_time,
    }
    for index, seat in pairs(tableobj.seats) do
        tablelogic.sendmsg_to_tableplayer(seat.rid, "stopbetN", noticemsg)
    end

    tableobj.state = ECQSSCTableState.TABLE_STATE_WAIT_OPEN_AWARD
    local noticemsg = {
        table_index = tableobj.conf.table_index,
    }
    local timer_id = timer.settimer(award_left_time * 100, "openaward", noticemsg)
    if tableobj.state ~= ECQSSCTableState.TABLE_STATE_WAIT_OPEN_AWARD then
        timer.cleartimer(timer_id)
    else
        tableobj.timer_id = timer_id
    end
end
--开奖
--
function GameLogic.openaward(gameobj, is_recall)
    local tableobj = gameobj.tableobj
    local openaward_result = {}
    local rand_result = nil
    local gamename = tablelogic.get_gamename(tableobj)
    local noticemsg = {
        open_awarding_time = timetool.get_time() + 5 * 60, 
    }
    tablelogic.sendmsg_to_alltableplayer(tableobj, "openawardingN", noticemsg)
    --延时等待
    tableobj.state = ECQSSCTableState.TABLE_STATE_WAIT_HANDLE_OPEN_AWARD_RESULT
    local timernotice = {
        table_index = tableobj.conf.table_index,
    }
    local timer_id = timer.settimer(1 * 100, "handle_awardresult", timernotice)
	if tableobj.state ~= ECQSSCTableState.TABLE_STATE_WAIT_HANDLE_OPEN_AWARD_RESULT then
		timer.cleartimer(timer_id)
	else
		tableobj.timer_id = timer_id
	end
end

--[Comment]
--
--处理开牌结果
--
function GameLogic.handle_openawardresult(gameobj)
    local tableobj = gameobj.tableobj
    local openaward_result = {}
    local rand_result = nil
    local gamename = tablelogic.get_gamename(tableobj)
    --获取已做庄局数
    --获得随机结果
    ---filelog.sys_error("----------GameLogic.openaward-------", tableobj.get_lottery_result_from_url)
    rand_result = skynet.call(".slotmgr","lua","get_lottery_result_by_points", tableobj.get_lottery_result_from_url)
    openaward_result = tabletool.deepcopy(rand_result.points)
    --检测随机结果
    -- local is_ok = GameLogic.check_spin_result(tableobj, openaward_result, rand_result)
    -- if not is_ok then
    --     return GameLogic.opencard(gameobj,true)
    -- end
    --计算延时时间,1张牌延时1s
    --通知玩家
    local noticemsg = {
        open_award_points = {}
    }
    for index, point in ipairs(rand_result.points) do
        table.insert(noticemsg.open_award_points, point)
    end
    tablelogic.sendmsg_to_alltableplayer(tableobj, "openawardN", noticemsg)
    tableobj.rand_result_list = rand_result

    local odds_list = tableobj.odds_list
    local rand_result = tableobj.rand_result_list or {}
    local opencard_result = rand_result.prize_ids or {}
    local double_num = 1    --翻倍数
    for _,seat in pairs(tableobj.seats) do
        if seat.state == ECQSSCSeatState.SEAT_STATE_PLAYING then
            for _,id in pairs(opencard_result) do
                local bet_id = id
                if seat.cur_bet_list[bet_id] and seat.cur_bet_list[bet_id] > 0 then
                    ---local real_id = id * 100
                    seat.curr_score = seat.curr_score + seat.cur_bet_list[bet_id] * double_num * (odds_list[bet_id] or 0)
                    table.insert(seat.hit_fruit_list,id)
                end
            end  
        end
    end
    --filelog.sys_error("----------GameLogic.handle_openawardresult-------")
    local gamename = tablelogic.get_gamename(tableobj)
    tableobj.state = ECQSSCTableState.TABLE_STATE_WAIT_ONE_GAME_END
    local timer_id = timer.settimer(1 * 100, "onegameend")	
	if tableobj.state ~= ECQSSCTableState.TABLE_STATE_WAIT_ONE_GAME_END then
		timer.cleartimer(timer_id)
	else
		tableobj.timer_id = timer_id
	end
end

--[Comment]
--  一局游戏结束
--  gameobj 游戏对象，{stateevent,tableobj}
--
function GameLogic.onegameend(gameobj)
    local tableobj = gameobj.tableobj

    --保存结束时间
    tableobj.one_end_time = timetool.get_time()

	--清空计时器
	if tableobj.timer_id > 0 then
		timer.cleartimer(tableobj.timer_id)
		tableobj.timer_id = -1
	end

	--一轮游戏结算
    GameLogic.onegameend_balance(gameobj)

    --更改每个座位总分
	for _, seat in pairs(tableobj.seats) do
		if not seatlogic.is_empty(seat) then
			seat.total_score = seat.total_score + seat.balance_score
		end
	end
    
    --设置桌子状态为：一局游戏真正结束
	tableobj.state = ECQSSCTableState.TABLE_STATE_ONE_GAME_REAL_END
end

--[Comment]
--  一局游戏真正结束
--  gameobj 游戏对象，{stateevent,tableobj}
--
function GameLogic.onegamerealend(gameobj)
	local tableobj = gameobj.tableobj

    tableobj.is_onegameend = true
   
    --通知结算金钱变化
    --保存牌局记录
    GameLogic.onegameend_save_tablerecord(gameobj)
    
    --获得游戏结果
	local noticemsg = GameLogic.get_game_result(gameobj)

    --向机器人服务更新游戏数据
    ---GameLogic.send_gameinfo_to_robotmgr(gameobj)

    --重置桌子数据,座位数据
	GameLogic.onegameend_inittable(gameobj)

    --发送结算
    local max_win = 0
    local max_win_rolename = nil
    for _,seat in pairs(tableobj.seats) do
        if not seatlogic.is_empty(seat) then
            if max_win < seat.balance_score then
                max_win = seat.balance_score
                max_win_rolename = seat.playerinfo.rolename
            end
            local cur_noticemsg = tabletool.deepcopy(noticemsg)
            cur_noticemsg.table_gameinfo = tablelogic.copy_table_gameinfo(seat.index)
            if seat.playerinfo.level ~= 99 then
                tablelogic.sendmsg_to_tableplayer(seat.rid, "gamebalanceN", cur_noticemsg)
            end
        end
    end

    if tablelogic.is_diamondtable() then
        GameLogic.game_balance_diamond(gameobj)
    end

    --设置了结束标记,删除桌子
    if tableobj.tableend_flag then
        skynet.call(tableobj.table_service,"lua","cmd","delete", ECQSSCTableDeleteReason.DELETE_REASON_SYSTEM_REQUIRE)
        return
    end
    --等待一局开始
    tableobj.state = ECQSSCTableState.TABLE_STATE_WAIT_ONE_GAME_START

    local timer_id = timer.settimer(10, "onegamestart")	
	if tableobj.state ~= ECQSSCTableState.TABLE_STATE_WAIT_ONE_GAME_START then
		timer.cleartimer(timer_id)
	else
		tableobj.timer_id = timer_id
	end
end

--[Comment]
--  游戏结束
--  gameobj 游戏对象，{stateevent,tableobj}
--
function GameLogic.gameend(gameobj)
	local tableobj = gameobj.tableobj

	tableobj.state = ECQSSCTableState.TABLE_STATE_UNKNOW   --设置桌子状态为：未知
    if tableobj.game_records ~= nil then
	    tableobj.game_records.end_time = tableobj.end_time or timetool.get_time()
	    tableobj.game_records.final_to_num = tableobj.curr_to_num    --最终局数
    end

	--强制踢掉玩家
    if tablelogic.get_sitdown_player_num(tableobj) > 0 then
		tablelogic.leavetableallplayer(tableobj, EStandupReason.STANDUP_REASON_DELETE_TABLE)
		local waits = tabletool.deepcopy(tableobj.waits)
		for rid, waitinfo in pairs(waits) do
			tablelogic.passive_leavetable(tableobj, rid,waitinfo.playerinfo.diamond)
		end
	end

	--检查桌子当前是否能够删除
	if tableobj.delete_table_timer_id <= 0 then
		tableobj.delete_table_timer_id = -1
	end

    tableobj.is_had_start = false

    --倒计时删除,1s
    if tableobj.delete_table_timer_id == -1 then
        tableobj.delete_table_timer_id = timer.settimer(100, "delete_table")
    end
end

------------------------------------------------------------------
----其他方法

--[Comment]
--  坐下
--  gameobj 游戏对象，{stateevent,tableobj}
--
function GameLogic.on_sitdown_table(gameobj, seat)
    local tableobj = gameobj.tableobj
	if tableobj.delete_table_timer_id > 0 then
		timer.cleartimer(tableobj.delete_table_timer_id)
		tableobj.delete_table_timer_id = -1
	end 
end

--[Comment]
--  等待坐下
--  gameobj 游戏对象，{stateevent,tableobj}
--
function GameLogic.wait_player_sitdown(gameobj)
	local tableobj = gameobj.tableobj
    if tableobj.sitdown_player_num <= 0 and tableobj.cur_watch_playernum <= 0 then
        if tableobj.delete_table_timer_id > 0 then
			timer.cleartimer(tableobj.delete_table_timer_id)
			tableobj.delete_table_timer_id = -1
		end
        --倒计时删除桌子
 		--tableobj.delete_table_timer_id = timer.settimer(10 * 100, "delete_table")
    end
end
-----------------------------
--init类

--[Comment]
-- 第一局游戏开始时，初始化桌子
--
function GameLogic.gamestart_inittable(gameobj)
    --tableobj即table_data
	local tableobj = gameobj.tableobj

    --初始化桌子数据
	tableobj.end_time = 0                       --桌子结束时间
	tableobj.isdeleting = false                 --是否将被删除
	tableobj.is_onegameend = false              --是否一局游戏结束
    tableobj.start_pos = 1
    tableobj.end_pos = 0
    tableobj.prize_id = nil
    tableobj.extprize_item = nil
    tableobj.banker_seat_index = 0
    if tableobj.curr_to_num <= 0 or tableobj.start_time == 0 then
        tableobj.start_time = timetool.get_time() --游戏开始时间
    end

    --保存游戏记录
    if tableobj.game_records then
        tableobj.game_records.start_time = tableobj.start_time
        if not tableobj.game_records.history_prize_list then
            tableobj.game_records.history_prize_list = {}
        end
    end
end

--排序函数
--不稳定的排序会导致错误
--两值相等时必须返回false
local function comp(item1, item2)
    if item1 == nil or item2 == nil then
        return false
    end
    if item1.diamond < item2.diamond then
        return false
    elseif item1.diamond == item2.diamond then
        if item1.win_num < item2.win_num then
            return false
        elseif item1.win_num == item2.win_num then
            if item1.value < item2.value then
                return false
            elseif item1.value == item2.value then
                return false
            end
        end
    end
    return true
end
--[Comment]
-- 每局游戏开始时，初始化桌子
--
function GameLogic.onegamestart_inittable(gameobj)
	local tableobj = gameobj.tableobj
	local now = timetool.get_time()

	tableobj.one_start_time =  now          --本局开始时间
    tableobj.one_end_time = 0               --本局结束时间
    tableobj.action_timeout_time = 0        --当前操作超时时间

    --本局局号
    tableobj.curr_round_code = string.format("%04d",now % 10000)

    --一局结束的标记
	tableobj.is_onegameend = false              --是否一局结束
    tableobj.is_ingame = true                   --是否游戏中
    tableobj.cur_robot_num = 0                  --当前机器人数
    tableobj.cur_robot_list = {}                --当前机器人列表

    --重新获取抽水率
    local gamename = tablelogic.get_gamename(tableobj)
    local status,cur_rate = skynet.pcall(skynet.call, ".slotmgr", "lua", "get_service_fee_rate", gamename)
    if status and cur_rate then
        tableobj.service_fee_rate = tonumber(cur_rate) or 0.025
    end

    --初始化座位
    for _,seat in pairs(tableobj.seats) do
        if not seatlogic.is_empty(seat) and seat.had_ready then
            seatlogic.onegamestart_initseat(seat)
            if seat.is_robot then
                tableobj.cur_robot_num = tableobj.cur_robot_num + 1
                table.insert(tableobj.cur_robot_list,seat.rid)
            end
       end
    end
    
    --重置通用计时器
	if tableobj.timer_id >= 0 then
		timer.cleartimer(tableobj.timer_id)
		tableobj.timer_id = -1
	end

    tableobj.has_resettable = nil
    tableobj.cur_bet_player_num = 0
    tableobj.cur_total_bet_num = 0
    tableobj.cur_total_bet_cnt = 0
    tableobj.sys_peijiang = 0
    tableobj.all_service_fee = 0
    tableobj.cur_total_bet_list = tablelogic.gen_bet_list(tableobj)         --总下注列表
    tableobj.cur_total_player_bet_cnt = {}

    tableobj.each_total_bet_cnt_list = {}   --每一个下注项不同底注的下注次数
    tableobj.each_inc_bet_cnt_list = {}     --每一个下注项不同底注的下注次数的变化列表
    tableobj.all_player_betinfo = {}

    local get_curr_qishu = skynet.call(".slotmgr", "lua", "get_curr_qishu_string", now)
    local get_last_qishu = skynet.call(".slotmgr", "lua", "get_last_qishu", now)
    local get_stop_bet_time = skynet.call(".slotmgr", "lua", "get_stop_bet_time", now)
    local open_award_time = skynet.call(".slotmgr", "lua", "get_open_award_time", get_stop_bet_time)
    tableobj.cur_qishu = get_curr_qishu
    tableobj.last_cur_qishu = get_last_qishu
    tableobj.open_award_time = open_award_time
    tableobj.curr_qishu_stop_bet_time = get_stop_bet_time
    ---tableobj.curr_qishu_stop_bet_time = timetool.get_time() + tableobj.do_bet_timeout
    ----检查系统是否破产
    local status, is_break = skynet.pcall(skynet.call, ".openaward", "lua", "check_system_break")
    if status == true and is_break == true then
        filelog.sys_error("--------system breakout --------")
        local status, result = skynet.pcall(skynet.call, ".router", "lua", "set_gameend_flag")
    end
end

--[Comment]
-- 每局游戏结束时，初始化桌子
--
function GameLogic.onegameend_inittable(gameobj)
	local tableobj = gameobj.tableobj

    tableobj.one_start_time = 0	      --开始时间要先清空，游戏开始时再设置
    tableobj.is_ingame = false        --是否游戏中
    tableobj.curr_round_code = ""
    tableobj.start_pos = tableobj.end_pos or tableobj.start_pos
    tableobj.end_pos = 0
    tableobj.prize_id = nil
    tableobj.extprize_item = nil
    tableobj.start_prize_list = nil
    tableobj.opencard_result = nil  --开奖结果
    tableobj.cur_total_bet_list = {}
    tableobj.each_total_bet_cnt_list = {}
    tableobj.each_inc_bet_cnt_list = {}

    --初始化座位
    for _,seat in pairs(tableobj.seats) do
        if not seatlogic.is_empty(seat) and seat.had_ready then
            seatlogic.onegameend_initseat(seat)
        end
    end

    if tableobj.timer_id >= 0 then
		timer.cleartimer(tableobj.timer_id)
		tableobj.timer_id = -1
	end

end

--[Comment]
-- 初始化游戏记录(桌子创建时便被调用）
--
function GameLogic.init_game_records(tableobj)
    --游戏记录表（记录游戏数据）
	tableobj.game_records = { 
        --固定信息
        table_type = tableobj.table_type,               --桌子类型
		table_uuid = tableobj.uuid,                     --桌子uuid
        create_user_rid = tableobj.create_rid,          --创建者rid
        conf = tableobj.conf or { },                    --桌子配置
        delete_reason = 0,                              --删除原因
		create_time = tableobj.create_time,             --创建时间
        delete_time = 0,                                --删除时间
        start_time = 0,                                 --第一局开始时间
        end_time =  0,                                  --最后一局结束时间
		final_to_num = 0,                               --最终局数
        history_prize_list = {},                        --历史中奖记录
        table_code = tableobj.code,                     --桌号
        banker_win_num = 0,                             --庄家获胜数
        allplayer_win_num = {0,0,0},                    --闲家获胜数
	}

end

--[Comment]
--游戏开始初始化牌局记录
--
function GameLogic.onegamestart_init_tablerecord(gameobj)
    local tableobj = gameobj.tableobj

    --每局信息
    tableobj.game_records.cur_record_id = ""                             --本局记录日志id（log日志文件名）
    tableobj.game_records.curr_to_num = tableobj.curr_to_num or 0        --当前局数
    tableobj.game_records.one_start_time = tableobj.one_start_time or 0  --本局开始时间
    tableobj.game_records.one_end_time = 0                               --本局结束时间
    tableobj.game_records.table_tradeid = ""                             --本局唯一交易id
    tableobj.game_records.players_balance_list = {}                      --本局结算情况
    tableobj.game_records.sys_diamond_start = 0                          --系统开始钻石
    tableobj.game_records.sys_diamond_end = 0                            --系统结束钻石
    tableobj.game_records.user_count = 0                                 --游戏总人数
    tableobj.game_records.banker_seat_index = tableobj.banker_seat_index or 0       --庄家位置
    tableobj.game_records.role_info = { }                                           --玩家信息
    
    --初始化玩家信息
    for _,seat in pairs(tableobj.seats) do
        if GameLogic.is_ingame(gameobj,seat) and not seat.is_robot then
            local item = {
                sex = seat.playerinfo.sex,
                diamond = seat.playerinfo.diamond,
                coin = seat.playerinfo.coin,
                name = seat.playerinfo.rolename,
                logo = seat.playerinfo.logo,
                seat_index = seat.index,
             }
            tableobj.game_records.role_info[seat.rid] = item
        end
    end
                     
    --玩家开始前金钱情况
    tableobj.game_records.diamond_change_list = {}  
    tableobj.game_records.coin_change_list = {}                                 
    for _,seat in pairs(tableobj.seats) do
        if GameLogic.is_ingame(gameobj,seat) and not seat.is_robot then
            local item = { }
            item.gamestart_diamond = seat.playerinfo.diamond
            tableobj.game_records.diamond_change_list[seat.rid] = item
            tableobj.game_records.coin_change_list[seat.rid] = {gamestart_coin = seat.playerinfo.coin}
        end
    end
end

--[Comment]
--游戏结束更新牌局记录
--
function GameLogic.onegameend_save_tablerecord(gameobj)
    local tableobj = gameobj.tableobj

    --修改牌局记录
	if tableobj.game_records ~= nil then
        local game_records = tableobj.game_records
        game_records.user_count = 0
        game_records.one_end_time = tableobj.one_end_time or 0
        game_records.table_tradeid = tableobj.cur_table_tradeid or ""
        game_records.opencard_result = tableobj.rand_result_list
        
        --钻石变化
        local record_id = game_records.table_uuid .. "_"
        record_id = record_id .. game_records.one_start_time .. "_"
        record_id = record_id .. game_records.one_end_time .. "_"
        for _,seat in pairs(tableobj.seats) do
            if GameLogic.is_ingame(gameobj, seat) and not seat.is_robot then
                --金钱变化
                local ditem = game_records.diamond_change_list[seat.rid]
                local citem = game_records.coin_change_list[seat.rid]
                if not ditem then
                    game_records.diamond_change_list[seat.rid] = {gamestart_diamond = seat.playerinfo.diamond}
                    ditem = game_records.diamond_change_list[seat.rid]
                end
                if not citem then
                    game_records.coin_change_list[seat.rid] = {gamestart_coin = seat.playerinfo.coin}
                    citem = game_records.coin_change_list[seat.rid]
                end
                citem.winvalue = seat.playerinfo.coin - citem.gamestart_coin
                ditem.winvalue = seat.playerinfo.diamond - ditem.gamestart_diamond
                citem.gameend_coin = seat.playerinfo.coin
                ditem.gameend_diamond = seat.playerinfo.diamond

                --个人信息
                if not game_records.role_info[seat.rid] then
                    game_records.role_info[seat.rid] = {
                        sex = seat.playerinfo.sex,
                        diamond = seat.playerinfo.diamond,
                        coin = seat.playerinfo.coin,
                        name = seat.playerinfo.rolename,
                        logo = seat.playerinfo.logo,
                        seat_index = seat.index,
                    }
                end

                --结算
                if seat.state == ECQSSCSeatState.SEAT_STATE_PLAYING then
                    if seat.is_robot then
                        game_records.user_count = game_records.user_count - 1
                    else
                        --结算相关
                        local balance_list = { }
                        --玩家rid
                        balance_list.rid = seat.rid
                        --本局下注
                        balance_list.diamond = seat.cur_total_bet
                        --输赢钻石数
                        balance_list.diamond_change = seat.balance_score or 0
                        --下注列表
                        balance_list.cur_bet_list = tabletool.deepcopy(seat.cur_bet_list)
                        --输赢状态，1：赢 0：输
                        if balance_list.diamond_change < 0 then
                            balance_list.state = 0
                        else
                            balance_list.state = 1
                        end
                        table.insert(game_records.players_balance_list,balance_list)
                        game_records.user_count = game_records.user_count + 1
                    end
                end
            end
        end
        record_id = record_id .. os.date("%Y%m%d_%H%M%S",game_records.one_start_time)
        game_records.cur_record_id = record_id

        --保存中奖记录
        local first_record = nil
        local history_prize_list = game_records.history_prize_list
        local maxlen = tableobj.max_history_record_num or 8
        while #history_prize_list >= maxlen do
            first_record = table.remove(history_prize_list,1)
        end
        local record = tabletool.deepcopy(tableobj.opencard_result)
        local record_str = json.encode(record)
        table.insert(history_prize_list,record_str)

        --每隔一天重置历史记录
        local ctm = os.date("*t",tableobj.one_end_time)
        if not tableobj.init_record_day then
            tableobj.init_record_day = os.date("*t",tableobj.start_time).day
        end
        if tableobj.init_record_day ~= ctm.day then
            if tableobj.curr_to_num > 20 then
                tableobj.game_records.banker_win_num = 0
                tableobj.game_records.allplayer_win_num = {0,0,0}
                tableobj.game_records.history_prize_list = {}
            end
            tableobj.init_record_day = ctm.day
        end
	end
    --写到日志
    tablelogic.save_table_records(tableobj.game_records)
end

-----------------------------------------------------------------------------
---check类
--

--[Comment]
--  检查玩家钱是否足够
--  gameobj 游戏对象，{stateevent,tableobj}
--
function  GameLogic.check_player_money(tableobj,seat)
    local min_carry_amount = tableobj.conf.min_carry_amount or 0
    local max_carry_amount = tableobj.conf.max_carry_amount or 0

    if not seat then
        return false
    end

    local money = tablelogic.get_curmoney(seat)
    if money < min_carry_amount or money > max_carry_amount then
        return false
    end

    return true
end

------------------------------------------------------------------------
--通知类方法
--

--[Comment]
--  通知所有玩家游戏开始
--  gameobj 游戏对象，{stateevent,tableobj}
--
 function GameLogic.send_gamestart_notice(gameobj)
	local tableobj = gameobj.tableobj
	local noticemsg = {
        table_gameinfo = {},
    }
    --自己信息
    for index,seat in pairs(tableobj.seats) do
        if not seatlogic.is_empty(seat) then
            local cur_noticemsg = tabletool.deepcopy(noticemsg)
            cur_noticemsg.table_gameinfo = tablelogic.copy_table_gameinfo(seat.index)
            tablelogic.sendmsg_to_tableplayer(seat.rid, "gamestartN", cur_noticemsg)
	   end
    end 
end

--向机器人服务更新游戏数据
function GameLogic.send_gameinfo_to_robotmgr(gameobj)
    local tableobj = gameobj.tableobj

    --统计不同底注下注次数
    local bet_score_list = {}
    local total_bet_cnt_list = tableobj.each_total_bet_cnt_list or {}
    if #total_bet_cnt_list ~= 0 then
        for _,item in pairs(total_bet_cnt_list) do
            for score,cnt in pairs(item) do
                bet_score_list[score] = (bet_score_list[score] or 0) + cnt
            end
        end
    end
    
    --统计玩家数
    local total_robot_num = 0
    local total_player_num = 0
    for _,seat in pairs(tableobj.seats) do
        if not seatlogic.is_empty(seat) and seat.had_ready then
            if not seat.is_robot then
                total_player_num = total_player_num + 1
            else
                total_robot_num = total_robot_num + 1
            end
        end
    end

    --通知机器人服务
    ---skynet.send(".robotmgr", "lua", "update_gameinfo",  bet_score_list, total_player_num, total_robot_num, tableobj.table_service)
end
------------------------------------------------------------------------
---修改数据类
--

--[Comment]
-- 重置桌子数据
--
function GameLogic.reset_tabledata(gameobj)
	local tableobj = gameobj.tableobj

    if tableobj.has_resettable then
        return
    end

    --初始化桌子数据
	tableobj.end_time = 0                       --桌子结束时间
	tableobj.isdeleting = false                 --是否将被删除
	tableobj.is_onegameend = false              --是否一局游戏结束
    tableobj.has_resettable = true
end


-----------------------------------------------------------
--clear类
--

--[Comment]
-- 站起后，删除座位对象
--
function GameLogic.standup_clear_seat(gameobj, seat)
    local tableobj = gameobj.tableobj
	seatlogic.clear_seat(seat)
end

---------------------------------------------------------------
---is类
--

--[Comment]
--判断座位对应玩家是否在游戏中
--
function GameLogic.is_ingame(gameobj, seat)
	return (seat.state > ECQSSCSeatState.SEAT_STATE_WAIT_START)
end

------------------------------------------------------------
---get类
--

--[Comment]
--  通知结算信息
--  gameobj 游戏对象，{stateevent,tableobj}
--
function GameLogic.get_game_result(gameobj)
	local tableobj = gameobj.tableobj
    local rand_result = tableobj.rand_result_list
    -----filelog.sys_error("---------get_game_result------", rand_result)
    --[[
        optional int32 table_index          = 1;                            //桌子id
        optional int32 table_type           = 2;                            //桌子类型
        repeated int32 points               = 3;                            //开奖点数数据
        repeated int32 openawards_result    = 4;                            //中奖的区域ID
        optional table_gameinfo table_gameinfo = 5;                         //桌子的信息
    --]]
	--通知游戏结算
	local noticemsg = {
		table_index = tableobj.index,                   --桌子id
		table_type = tableobj.conf.table_type,          --桌子类型
        points = {},
        openawards_result = {},
        table_gameinfo = {},
	}

    if rand_result then
        local openawards_result = tabletool.deepcopy(rand_result.prize_ids)
        for index, point in pairs(rand_result.points) do
            table.insert(noticemsg.points, point)
        end
        noticemsg.openawards_result = openawards_result
    end
    return noticemsg
end

--[Comment]
--获得游戏中玩家数
--
function GameLogic.get_ingame_playernum(gameobj)
	local tableobj = gameobj.tableobj
	local playernum = 0
	for _, seat in pairs(tableobj.seats) do
		if GameLogic.is_ingame(gameobj, seat) then
			playernum = playernum + 1
		end
	end
	return playernum
end

------------------------------------------------------------
---结算类
--

--[Comment]
--@ des 一轮结算
--@ gameobj 游戏对象
--
function GameLogic.onegameend_balance(gameobj)
    local tableobj = gameobj.tableobj
    --保存记录
    GameLogic.save_records(tableobj)
end

--[Comment]
--保存记录
--
function GameLogic.save_records(tableobj)
    local opencard_result = tableobj.opencard_result or {}
    local gamename = tablelogic.get_gamename(tableobj)
    skynet.send(".slotmgr","lua","save_prize_records",gamename, opencard_result)
end


local function get_des_betinfo(betinfos)
    local des_betinfo = ""
    if not betinfos or next(betinfos) == nil then
        return des_betinfo
    end
    local des_table = {}
    for bet_item_id, bet_num in pairs(betinfos) do
        local des_table_bes  = { des = "【".. ECQSSCdesbetid[bet_item_id] .. ", " .. tostring(math.floor( bet_num/ 200)) .. "倍】", bet_item_id = bet_item_id }
        table.insert(des_table, des_table_bes)
    end
    table.sort(des_table, function(first, second)
            if first.bet_item_id < second.bet_item_id then
                return true
            else
                return false
            end
        end)
    for index, desinfo in ipairs(des_table) do
        des_betinfo = des_betinfo .. desinfo.des
    end
    return des_betinfo
end

function GameLogic.game_balance_diamond(gameobj)
    --[[
    local tableobj = gameobj.tableobj
    local odds_list = tableobj.odds_list
    local rand_result = tableobj.rand_result
    local openaward_result = tableobj.rand_result_list
    local all_player_gets = {}


    for rid, bet_info in pairs(tableobj.all_player_betinfo) do
        if all_player_gets[rid] == nil then
            all_player_gets[rid] = {
                details = {},
                change = 0,
                real_change = 0,
            }
        end
        for bet_item_id, bet_num in pairs(bet_info) do
            all_player_gets[rid].details[bet_item_id] = all_player_gets[rid].details[bet_item_id] or 0
            for index, prize_id in pairs(openaward_result.prize_ids) do
                if bet_item_id == prize_id then
                    ---local real_id = bet_item_id * 100
                    all_player_gets[rid].details[bet_item_id] = all_player_gets[rid].details[bet_item_id] + bet_num * odds_list[bet_item_id]
                    all_player_gets[rid].change = all_player_gets[rid].change + bet_num * odds_list[bet_item_id]
                end
            end
            all_player_gets[rid].real_change = math.floor(all_player_gets[rid].change * (1 - 2 * tableobj.service_fee_rate) )
            tableobj.sys_peijiang = tableobj.sys_peijiang + all_player_gets[rid].real_change
            tableobj.all_service_fee = tableobj.all_service_fee + (all_player_gets[rid].change - all_player_gets[rid].real_change)
        end
    end
    local sys_in_come = tableobj.cur_total_bet_num - (tableobj.sys_peijiang + tableobj.all_service_fee)

    local comment = tablelogic.create_comment()
    local gamename =  tablelogic.get_gamename(tableobj)
    local status, result = skynet.pcall(skynet.call, ".slotmgr", "lua", "update_system_inventory", gamename, sys_in_come, comment)
    status, result = skynet.pcall(skynet.call, ".slotmgr", "lua", "update_system_profit", gamename, tableobj.all_service_fee, comment)
    local pointstring = ""
    for i = 5,1,-1 do
        pointstring = pointstring .. tostring(openaward_result.points[i])
    end
    ---通知gate发邮件
    for rid, get_info in pairs(all_player_gets) do
        if get_info.real_change > 0 then
            local strfmt = "" .. EMailContentAward
            local cur_qishu = tableobj.cur_qishu
            local betinfos = get_des_betinfo(tableobj.all_player_betinfo[rid])
            --第 %s 期开奖号码为%s,您购买了【 %s 】。恭喜你获得彩金 %d 元，请前往银行中领取彩金!
            local content = string.format(strfmt, cur_qishu, pointstring,  betinfos, get_info.real_change/100)
            local attachs = {diamond = get_info.real_change}
            local fields = {subject = EMailTitle, content = content }
            tablelogic.send_mail_to_player(rid, fields)
            local givefields = {    
                tradeid = comment.table_tradeid or "",
                sendname = "系统",
                recvname = "xxxxx",
                begin_value = 0,
                end_value = 0,
                recvrid = tonumber(rid),
                give_type = EGiveMoneyType.EGIVEMONEY_TYPE_CP_AWARD,
                give_value = tonumber(get_info.real_change),
                current_state = EGiveMoneySate.EGIVEMONEY_STATE_WAIT_DRAW,
                remark = "彩票中奖",
            }
            tablelogic.send_diamond_to_givesystem(rid, givefields)
        else
            local strfmt = "" .. EMailContentNoAward
            local cur_qishu = tableobj.cur_qishu
            local betinfos = get_des_betinfo(tableobj.all_player_betinfo[rid])
            local content = string.format(strfmt, cur_qishu, pointstring, betinfos)
            local fields = {subject = EMailTitle, content = content}
            tablelogic.send_mail_to_player(rid, fields)
        end
    end
    local nowtime = timetool.get_time()
    -----保存历史记录
    local one_record = {
        points = openaward_result.points,
        prize_ids = openaward_result.prize_ids,
        open_award_time = nowtime, 
        open_qishu = tableobj.cur_qishu,
        bet_info = tabletool.deepcopy(tableobj.all_player_betinfo),
        player_get_info = tabletool.deepcopy(all_player_gets)
    }

    if tableobj.all_player_historys ==  nil then
        tableobj.all_player_historys = {}
    end
    table.insert(tableobj.all_player_historys, one_record)
    --]]
    return true
end

return GameLogic